package com.zui.webapp.action;

import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;

import com.zui.entity.BaseEntity;
import com.zui.entity.product.Catalog;
import com.zui.entity.product.Category;
import com.zui.entity.product.Feature;
import com.zui.entity.product.Geo;
import com.zui.entity.product.Image;
import com.zui.entity.product.Product;
import com.zui.entity.product.ProductImage;
import com.zui.entity.setup.Uom;
import com.zui.entity.trade.Trade;
import com.zui.manager.GeoManager;
import com.zui.manager.ImageManager;
import com.zui.manager.SessionManager;
import com.zui.manager.TradeManager;
import com.zui.security.User;
import com.zui.util.JqGridPage;
import com.zui.util.Page;
import com.zui.util.UploadedJQFile;
import com.zui.util.ZuiConstants;

@SuppressWarnings({"unchecked","rawtypes"})
public class TradeAction extends BaseJQGridAction {

	private static final long serialVersionUID = 1L;
	private static final Log log = LogFactory.getLog(TradeAction.class);
	
	private Catalog catalog;
	private Category category;
	private Trade trade;
	private Geo geo;
	private List<Trade> list;
	private List<Geo> areaList;
	public TradeAction() {}
	public TradeAction(SessionManager sessionManager) {
		this.sessionManager = sessionManager;
	}
	
	@Autowired
	private SessionManager sessionManager;
	@Autowired
	private TradeManager tradeManager;
	@Autowired
	private ImageManager imageManager;
	@Autowired
	private GeoManager geoManager;
	
	/***********************************************************
	 * Business Method start
	 **********************************************************/
	public String showSelectCategoryPage() {
		if (super.getCurrentUser() == null)
			return "showLoginPage";
		catalog = (Catalog)sessionManager.findById(Catalog.class, BaseEntity.BASE_CATALOG_Id);
		return "selectCategory";
	}
	/**
	 * depending on different category, the fillInfo page should be different.
	 * @return
	 */
	public String showFillInfoPage() {
		if (category == null || category.getId() == null)
			return showSelectCategoryPage();
		category = (Category)sessionManager.findById(Category.class, category.getId());
		areaList = geoManager.findGeosByGeoTypeId("CHN_B");
		
		if (trade == null)
			trade = new Trade();
		trade.setCurrencyUom((Uom)sessionManager.findById(Uom.class, Uom.UOM_CURRENCY_CNY));
		trade.setGeoCity(geoManager.findGeoByIp(super.getRemoteIpAddress()));
		return "fillInfo";
	}
	public String postAd() {
		User user = super.getCurrentUser();
		if (user == null || trade == null)
			return "showLoginPage";
		if (trade==null || trade.getProduct()==null)
			return showFillInfoPage();
		
		trade.setCreatedByUserLogin(super.getCurrentUserName());
		trade.setCreatedDate(Calendar.getInstance().getTime());
		trade.setLastModifiedByUserLogin(super.getCurrentUserName());
		trade.setLastModifiedDate(Calendar.getInstance().getTime());
		
		if (trade.getCommercialFlag()==null || "".equals(trade.getCommercialFlag().trim()))
			trade.setCommercialFlag(BaseEntity.FLAG_N);

		/*------- Setup Product --------*/
		Product product = trade.getProduct()==null?new Product():trade.getProduct();
		product.setInternalName(trade.getTitle());
		
		if (trade.getFeatureIds()!=null)
			for (String featurId:trade.getFeatureIds()) {
				if (featurId != null && !featurId.trim().equals(""))
					product.addProductFeatureAppl(new Feature(featurId));	
			}
				
		
		if (trade.getImageIds()!=null) {
			for (String imageId:trade.getImageIds()) {
				if (imageId != null && !imageId.trim().equals(""))
					product.addProductImage(new Image(imageId));
			}
				
		
			product.getProductImages().get(0).setPrimaryFlag(BaseEntity.FLAG_Y);			
		}

		trade.setProduct(product);				
		trade = tradeManager.postAd(trade,user);
		return "viewAction";
	}
	public String addTradeProductImage() {
		
    	category = trade.getProduct().getPrimaryCategory();
    	String relativePath = Image.DEFAULT_IMAGE_RELATIVE_PATH 
    			+ System.getProperty("file.separator")
    			+ "Product" 
    			+ System.getProperty("file.separator") 
    			+ category.getId();
    	String realPath = ServletActionContext.getServletContext().getRealPath("/") + relativePath;
    	Image image = new Image(uploadedFile, uploadedFileFileName, super.getAppContextPath(),relativePath, realPath);
    	
    	imageManager.addImage(image);
    	
		UploadedJQFile uf = new UploadedJQFile(image.getId(),
				uploadedFileFileName,
				image.getOriginalImageFileSize(),
				image.getOriginalImageUrl(),
				image.getListViewImageUrl(),
				super.getAppContextPath()+"/image!deleteImage.action?image.id="+image.getId());
		uploadedJQFiles.add(uf);
		
    	return "imageAdded";
	}
	public String listUploadedImage() {
		
		if (trade==null||trade.getId()==null)
			return list();
		trade = tradeManager.loadById(trade.getId());
    	
		if (trade.getProduct() != null && trade.getProduct().getProductImages() !=null) {
			Iterator<ProductImage> it = trade.getProduct().getProductImages().iterator();
			while (it.hasNext()) {
				Image image = it.next().getImage();
				UploadedJQFile uf = new UploadedJQFile(image.getId(),
						image.getUploadedFileName(),
						image.getOriginalImageFileSize(),
						image.getOriginalImageUrl(),
						image.getListViewImageUrl(),
						super.getAppContextPath()+"/image!deleteImage.action?image.id="+image.getId());
				uploadedJQFiles.add(uf);				
				
			}
		}
    	return "uploadedImage";
	}	
	public String list() {
		String result = "ajaxlist";
		if (!ajax) {
			catalog = (Catalog)sessionManager.loadById(Catalog.class, ZuiConstants.CATALOG_IOBIKE);
			if(trade!=null && trade.getProduct()!=null &&trade.getProduct().getPrimaryCategory()!=null) 
				category = (Category)sessionManager.loadById(Category.class, trade.getProduct().getPrimaryCategory().getId());
			else
				category = (Category)sessionManager.loadById(Category.class, Category.CATEGORY_BIKES);
			
			areaList = geoManager.findGeosByGeoTypeId("CHN_B");
			geo = geoManager.findGeoByIp(super.getRemoteIpAddress());
			if (trade == null)
				trade = new Trade();
			trade.setGeoCity(geo);
			
			result = "list";
		}
		list = tradeManager.listTrades(trade, page==null?new Page():page);
		return result;
	}
	public String ajaxlist() {	
		list = tradeManager.listTrades(trade, page==null?new Page():page);
		return "list";
	}
	public String view() {
		if (trade==null||trade.getId()==null)
			return list();
		trade = tradeManager.loadById(trade.getId());
		trade.setViewedCount(trade.getViewedCount()+1);
		tradeManager.saveOrUpdate(trade);
		return "view";
	}	
	public String index() {return "index";}
	public String editNew() {
		catalog = new Catalog();
		return "editNew";
	}
	public String edit() {
		if (catalog.getId()==null)
			return "editNew";
		
		catalog = (Catalog)sessionManager.loadById(Catalog.class, catalog.getId());
		return "edit";
	}

	public String delete() {
		if (jq==null || jq.getId()==null ||jq.getId().trim().equals(""))
			return "index";
		sessionManager.deleteEngtityFlagByIds(Catalog.class, jq.getId().split("\\,"));
		/**
		 * @TODO: success message!
		 */
		return "index";
	}
	public String checkUniqueness() throws Exception {
		DetachedCriteria criteria = DetachedCriteria.forClass(Catalog.class);
		if (checkedField!=null && !"".equals(checkedField.trim())) {
			
			String methodName = "get" + checkedField.substring(0, 1).toUpperCase() + checkedField.substring(1);
			Method method = Catalog.class.getMethod(methodName);
			criteria.add(Restrictions.eq(checkedField, method.invoke(catalog)));
			valid = !sessionManager.checkExistence(criteria);
		}
		return "valid";
	}
	public String create() {
		catalog.setCreatedByUserLogin(super.getCurrentUserName());
		catalog.setCreatedDate(Calendar.getInstance().getTime());
		catalog.setLastModifiedByUserLogin(super.getCurrentUserName());
		catalog.setLastModifiedDate(Calendar.getInstance().getTime());
		sessionManager.saveEntity(catalog);
		return "view";
	}
	public String update() {

		Catalog tempCatalog = catalog;
		catalog = (Catalog)sessionManager.loadById(Catalog.class, catalog.getId());
		catalog.setName(tempCatalog.getName());
		catalog.setNameEn(tempCatalog.getNameEn());
		catalog.setDescription(tempCatalog.getDescription());
		catalog.setLastModifiedByUserLogin(super.getCurrentUserName());
		catalog.setLastModifiedDate(Calendar.getInstance().getTime());
		sessionManager.saveOrUpdate(catalog);
		return "view";
	}
	public String createAndNew() {
		this.create();
		catalog = null;
		return "editNew";
	}
	public String duplicate() {
		if (catalog.getId()==null)
			return "editNew";
		
		catalog = (Catalog)sessionManager.loadById(Catalog.class, catalog.getId());
		catalog.setId(null);
		catalog.setIsDeleted(BaseEntity.FLAG_N);
		return "editNew";
	}
	/**
	 * search the whole catalog list
	 * @return
	 */
	public String catalogJsonList() {
		DetachedCriteria criteria = DetachedCriteria.forClass(Catalog.class);
		if (jq !=null && jqFilters!=null) {
			jq.setGroupCriteria(criteria,jqFilters);
		}
		list = sessionManager.findByCriteriaForJQGrid(criteria,jq == null ? jq = new JqGridPage()
		: jq);
		
		//set null for session scope action
		jqFilters = null;
		return "catalogJsonList";
	}
	public void jqgridOper() {
		switch(jq.getOper()) {
			case del: delete();break;
			case add: create();break;
			case edit: create();break;
			default:break;
		}
	}
	

	/***********************************************************
	 * getters and setters
	 **********************************************************/
	/**
	 * @return the list
	 */
	public List<Trade> getList() {
		return list;
	}
	/**
	 * @param userList the userList to set
	 */
	public void setList(List<Trade> list) {
		this.list = list;
	}
	/**
	 * @return the catalog
	 */
	public Catalog getCatalog() {
		return catalog;
	}
	/**
	 * @param catalog the catalog to set
	 */
	public void setCatalog(Catalog catalog) {
		this.catalog = catalog;
	}
	public Category getCategory() {
		return category;
	}
	public void setCategory(Category category) {
		this.category = category;
	}
	public Geo getGeo() {
		return geo;
	}
	public void setGeo(Geo geo) {
		this.geo = geo;
	}
	public Trade getTrade() {
		return trade;
	}
	public void setTrade(Trade trade) {
		this.trade = trade;
	}
	public List<Geo> getAreaList() {
		return areaList;
	}
	public void setAreaList(List<Geo> areaList) {
		this.areaList = areaList;
	}
	
}
